今日這個單元,我們將一起探索 Spring Boot 如何像一位聰明的總機,接收來自網路世界的請求,並給予回應。
完成本單元後,你將能夠:
@Controller
, @RequestMapping
, @ResponseBody
, 和 @RestController
這些核心註解 (Annotation) 的作用。@Controller
- 應用程式的總機在 Spring Boot 應用程式中,@Controller
是一切的起點,它是你與使用者互動的橋樑。
簡單來說,它告訴 Spring 框架:「嘿!這個類別 (Class) 是個控制器,專門負責處理來自網頁瀏覽器的請求 (Request),並決定要回應 (Response) 什麼結果。」
你可以把 @Controller
想像成一間公司的總機。當有電話(HTTP 請求)打進來時,總機會先接聽,然後判斷來電者的意圖,再決定要轉接到哪個分機去處理。
import org.springframework.stereotype.Controller;
@Controller // 標記這個類別是一個總機 (控制器)
public class MyFirstController {
// ... 這裡將會定義各種分機 (處理方法)
}
@RequestMapping
& @GetMapping
- 指示轉接的分機號碼光有總機還不夠,我們需要告訴總機,什麼樣的來電該轉接到哪個分機。這就是 @RequestMapping
的工作。它負責建立「請求的網址 (URL)」和「處理該請求的方法 (Method)」之間的一一對應關係。
@Controller
:標記一個類別是總機。@RequestMapping
:標記一個方法是分機,並指定這個分機專門處理哪個 URL 的來電。在現代的 Spring Boot 開發中,為了讓程式碼更簡潔易讀,我們更常使用 @RequestMapping
的衍生註解 (Annotation),它們的語意更清晰:
@GetMapping
:專門處理 GET
請求(通常用於獲取資料)。@PostMapping
:專門處理 POST
請求(通常用於新增資料)。@PutMapping
:專門處理 PUT
請求(通常用於更新資料)。@DeleteMapping
:專門處理 DELETE
請求(通常用於刪除資料)。在今日入門單元,我們將聚焦在最常見的 @GetMapping
。
讓我們把總機和分機結合起來:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller // 這是一個總機
public class MyFirstController {
// 使用 @GetMapping 告訴總機:
// 如果有人用 GET 方式訪問 "/hello" 這個路徑,
// 就把請求轉交給下面的 sayHello() 方法處理。
@GetMapping("/hello")
public String sayHello() {
// 這個方法回傳了一個字串 "welcome"
return "welcome";
}
}
當你啟動程式並在瀏覽器輸入 http://localhost:8080/hello
,Spring Boot 會:
/hello
路徑的 GET
請求。@Controller
標記的 MyFirstController
類別中,尋找與 /hello
路徑匹配的 @GetMapping
。sayHello()
方法並執行它。"welcome"
。但這裡有一個關鍵問題:Spring 預設會把這個 "welcome"
當成一個視圖 (View) 的名稱,它會試圖去尋找一個叫做 welcome.html
的網頁檔案,然後把這個網頁的內容回傳給瀏覽器。
但如果我們不想回傳整個網頁,只想回傳 "Hello World" 這段文字資料呢?這就需要下一站的工具了。
@ResponseBody
- 我回傳的是「資料」,不是「網頁」!@ResponseBody
這個註解 (Annotation) 的核心任務非常明確,就是告訴 Spring 框架:
「請不要把我的回傳值當成視圖 (View) 名稱去尋找網頁檔案。請直接把這個回傳的內容,當作 HTTP 回應的主體 (Body) 送回去!」
這在開發 API 時至關重要,因為 API 的目的就是提供純粹的資料(最常見的是 JSON 格式),而不是完整的 HTML 頁面。
讓我們來改造一下剛剛的例子:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyFirstController {
@GetMapping("/hello-page")
public String sayHelloPage() {
// 沒有 @ResponseBody,Spring 會去找 welcome.html
return "welcome";
}
@GetMapping("/hello-data")
@ResponseBody // 加上這個註解!
public String sayHelloData() {
// 有了 @ResponseBody,Spring 會直接把 "Hello, World!" 這個字串回傳
return "Hello, World!";
}
}
現在:
/hello-page
,Spring 會去找 welcome.html
。/hello-data
,瀏覽器會直接收到 Hello, World!
的純文字。@ResponseBody
最強大的地方在於,它能自動將 Java 物件轉換成 JSON 格式。這得益於 Spring Boot 內建的 Jackson 函式庫 (Library)。
範例:回傳一個物件
// 假設你有一個 User 物件
public class User {
private String name;
private int age;
// ... 省略建構子、getter 和 setter
}
@Controller
public class UserController {
@GetMapping("/api/user")
@ResponseBody // 告訴 Spring 直接回傳這個物件
public User getUser() {
User user = new User("John Doe", 30);
// Spring 會自動將這個 user 物件序列化 (Serialize) 成 JSON
return user;
}
}
當你訪問 /api/user
,你會在瀏覽器中看到標準的 JSON 格式資料:
{
"name": "John Doe",
"age": 30
}
@RestController
- API 開發的標準配備看到這裡,你可能會發現,在開發 API 時,我們幾乎總是需要同時使用 @Controller
和 @ResponseBody
。
Spring 的設計者也想到了這一點,於是提供了一個更方便的複合註解 (Composite Annotation):@RestController
。
@RestController
= @Controller
+ @ResponseBody
當你在一個類別上使用 @RestController
,就等於告訴 Spring:「這個類別是一個專門用來提供 API、回傳資料的控制器,它裡面所有方法都預設啟用了 @ResponseBody
的功能!」
這是現代 Spring Boot API 開發的標準作法。
現在,讓我們用最精簡、最標準的方式來完成我們最初的目標。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
// 使用 @RestController,兼具 @Controller 和 @ResponseBody 的功能
@RestController
public class HelloApiController {
// 當使用者用 GET 方法訪問 "/api/hello" 路徑時,執行此方法
@GetMapping("/api/hello")
public String sayHello() {
// 因為 @RestController 的關係,這個字串會直接被回傳
return "Hello, World!";
}
}
就是這麼簡單!
@RestController
: 宣告這是一個專門回傳資料的 API 控制器。@GetMapping("/api/hello")
: 將 http://localhost:8080/api/hello
這個路徑的請求,交給 sayHello()
方法處理。return "Hello, World!"
: 方法回傳的字串,會直接成為瀏覽器收到的內容。現在,啟動你的 Spring Boot 應用程式,打開瀏覽器訪問 http://localhost:8080/api/hello
,你就能看到你的第一個 API 成功地回傳了 "Hello, World!"。
恭喜你,已經掌握了 Spring Boot 處理 Web 請求與回應的核心觀念!